<?php
include "config.php";
include_once "parse.php";
$_open = false;
$_dbh = null;
class api
{
    public function __construct()
    {
        global $config, $_dbh, $_open;
        if(!$_open)
        {
            if($_dbh = new PDO("mysql:host={$config['mysql']['server']};dbname={$config['mysql']['database']}", $config['mysql']['user'], $config['mysql']['password']))
            {
                $_dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
                $_open = true; # Set global $_open variable to true so that you won't have multiple connections
            }
        }
    }
    public function q($sql,$params = null,$assoc = true)
    {
        global $_dbh;
        $ret = array();
        $m = ($assoc) ? PDO::FETCH_ASSOC : PDO::FETCH_NUM;
        $statement = $_dbh->prepare($sql);
        $params = (array) $params;
        if($params) $q = $statement->execute($params);
        else $q = $statement->execute();
        if(substr($sql,0,6) == "UPDATE" or substr($sql,0,6) == "INSERT" or substr($sql,0,7) == "REPLACE") return $q;
        else
        {
            if(!$q) return false;
            else $q = $statement->fetchAll($m);
            foreach($q as $v) $ret[] = $v;
            while(count($ret) == 1 and is_array($ret[0])) $ret = $ret[0];
            foreach($ret as $k => $v)
            {
                if(is_array($v) and count($v) == 1)
                {
                    $vs = array_values($v);
                    $ret[$k] = $vs[0];
                }
            }
            return $ret;
        }
    }
    public function query($type,$data = null, $ext = false)
    {
        if(!$data && $type != "forums") return false;
        return $this->$type($data,$ext);
    }
    public function get($type,$value,$data = null, $ext = false)
    {
        if(!$data) return false;
        $res = api::$type($data,$ext);
        return $res[$value];
    }    
    private function user($data,$ext = false)
    {
        global $config;
        $sql = 'SELECT * FROM '. $config['mysql']['prefix'] .'users WHERE ';
        if(!is_array($data))
        {
            $uid = (int) $data;
            $sql .= 'user_id='.$uid;
        }
        else
        {
            if(!isset($data['id']))
            {
                $av = array_keys($data);
                $k = $av[0];
                $sql .= 'user_'. $k .'=?';
                $params = array($data[$k]);
            }
            elseif(isset($data['id']))
            {
                $uid = $data['id'];
                $sql .= 'user_id='.$uid;
            }
            else return false;
        }
        $result = api::q($sql,$params);
        if(!$result) return false;
        $res = array("contact" => array());
        $contacts = array("email","aim","msn","yahoo","gtalk","skype");
        foreach($result as $k => $v)
        {
            $k = explode("_",$k,2);
            $k = $k[1];
            if($v === "") $v = null;
            if(in_array($k,$contacts)) $res['contact'][$k] = $v;
            else $res[$k] = $v;
        }
        $res["raw"] = $res["signature"];
        $res["signature"] = parser::parse($res["raw"]);
        $res["topics"] = api::q('SELECT topic_id as id, topic_title as title, topic_body as body FROM '. $config['mysql']['prefix'] .'topics WHERE user_id='. $res['id']);
        $res["posts"] = count(api::q('SELECT post_id FROM '. $config['mysql']['prefix'] .'posts WHERE user_id='. $res['id']));
        // Assign rank number based on level
        if($res["level"] == "admin") $res["rank"] = 3;
        elseif($res["level"] == "mod") $res["rank"] = 2;
        elseif($res["level"] == "user") $res["rank"] = 1;
        else $res["rank"] = 0;
        // Get user preferences
        $prefs = $res["preferences"];
        $res["preferences"] = array();
        foreach(explode(',',$prefs) as $c2)
        {
            list($k,$v) = explode(':',$c2);
            $res["preferences"][$k] = str_replace(array('"'),array(""),$v);
        }
        if($ext) $res["_type"] = "user";
        return $res;
    }
    private function post($data, $ext = false)
    {
        global $config;
        $pid = (int) (is_array($data)) ? $data['pid'] : $data;
        $result = api::q('SELECT * FROM '. $config['mysql']['prefix'] .'posts WHERE post_id='. $pid);
        if(!$result or !$pid) return false;
        $res = array();
        foreach($result as $k => $v)
        {
            $k = explode("_",$k,2);
            if($k[0] == "user") $k[1] = "u{$k[1]}";
            if($k[0] == "topic") $k[1] = "t{$k[1]}";
            $k = $k[1];
            if($v === "") $v = null;
            else $res[$k] = $v;
        }
        $uid = $res["uid"];
        unset($res["uid"]);
        # Get user info so that multiply queries don't need to be made.
        $res["user"] = api::user($uid);
        $res["raw"] = $res["body"];
        $res["body"] = parser::parse($res["body"]);
        if($ext) $res["_type"] = "post";
        return $res;
    }
    private function topic($data, $ext = false)
    {
        global $config;
        $tid = (int) (is_array($data)) ? $data['tid'] : $data;
        $asc = (isset($data['order']) && $data['order'] == "asc") ? true : false;
        $result = api::q('SELECT * FROM '. $config['mysql']['prefix'] .'topics WHERE topic_id='. $tid);
        if(!$result or !$tid) return false;
        $res = array("lp" => false);
        foreach($result as $k => $v)
        {
            $k = explode("_",$k,2);
            if($k[0] == "user") $k[1] = "u{$k[1]}";
            if($k[0] == "forum") $k[1] = "f{$k[1]}";
            $k = $k[1];
            if($v === "") $v = null;
            $res[$k] = $v;
        }
        $uid = $res["uid"];
        unset($res["uid"]);
        # Get user info so that multiply queries don't need to be made.
        $res["user"] = api::user($uid);
        # Get list of post IDs
        $sql = 'SELECT post_id FROM '. $config['mysql']['prefix'] .'posts WHERE topic_id='. $tid .' ORDER BY post_date ASC';
        $psql = api::q($sql,null,false);
        $res["nposts"] = $nposts = count($psql);
        $pages = 1;
        if($nposts)
        {
            # Last post
            $lpid = api::q('SELECT post_id FROM '. $config['mysql']['prefix'] .'posts WHERE topic_id='. $tid .' ORDER BY post_date DESC LIMIT 1');
            $lpid = $lpid["post_id"];
            $res["lp"] = api::post($lpid,true);
            # Post pagination
            $perpage = (is_array($data) and isset($data['pp'])) ? $data['pp'] : 15;
            $pages = ceil($nposts / $perpage);
            $page = (int) (array_key_exists("page",$data) && $data['page'] <= $pages) ? $data['page'] : 1;
            $end = $perpage * $page;
            $end = ($end > $nposts) ? $nposts : $end;
            $start = $perpage * ($page - 1);
            $sql = array_slice($psql,$start,$end);
            if(!$sql) $res["posts"] = false;
            else
            {
                $res["posts"] = array();
                foreach($sql as $i) $res["posts"][] = api::post($i);
            }
        }
        $res["pages"] = ($pages) ? $pages : 1;
        $res["raw"] = $res["body"];
        $res["body"] = parser::parse($res["body"]);
        $res["desc"] = parser::parse($res["desc"]);
        $res["fname"] = api::q('SELECT forum_name FROM '. $config['mysql']['prefix'] .'forums WHERE forum_id='. $res["fid"]);
        $res["fname"] = $res["fname"]["forum_name"];
        if($ext) $res["_type"] = "topic";
        return $res;
    }
    private function forum($data, $ext = false)
    {
        global $config;
        $fid = (int) (is_array($data)) ? $data['fid'] : $data;
        $result = api::q('SELECT * FROM '. $config['mysql']['prefix'] .'forums WHERE forum_id='. $fid);
        if(!$result or !$fid) return false;
        $res = array("topics" => array());
        foreach($result as $k => $v)
        {
            $k = explode("_",$k,2);
            $k = $k[1];
            if($v === "") $v = null;
            else $res[$k] = $v;
        }
        # Pagination
        $tsql = api::q('SELECT topic_id FROM '. $config['mysql']['prefix'] .'topics WHERE forum_id='. $fid .' ORDER BY topic_lastpost DESC');
        $ntopics = count($tsql);
        $res['ntopics'] = $ntopics;
        if($ntopics and $fid)
        {
            $page = (int) ($data['page']) ? $data['page'] : 1;
            $perpage = (int) ($data['pp']) ? $data['pp'] : 15;
            if($ntopics > 1)
            {
                $res["pages"] = ceil($ntopics / $perpage);
                $start = $perpage * ($page-1);
                $topics_picked = array_slice($tsql,$start,$perpage);
                foreach($topics_picked as $tid)
                {
                    $t = api::topic($tid,true);
                    $res["topics"][] = $t;
                }
            }
            else $res["topics"][] = api::topic($tsql["topic_id"],true);
        }
        else
        {
            $res["pages"] = 1;
            $res["topics"] = array();
        }
        $res["desc"] = parser::parse($res["desc"]);
        $res["_type"] = "forum";
        return $res;
    }
    private function forums($data, $ext)
    {
        global $config;
        $result = api::q('SELECT forum_id FROM '. $config['mysql']['prefix'] .'forums');
        if(!$result) return false;
        $res = array();
        foreach($result as $fid) $res[] = api::forum($fid,true);
        $res["_type"] = "forums";
        return $res;
    }
    # Misc. Database functions
    public function inc($table)
    {
        global $config;
        $status = api::q('SHOW TABLE STATUS WHERE name = \''. $config['mysql']['prefix'] . $table .'\'');
        return $status["Auto_increment"];
    }
    # Generators
    private function array_expand($arr,$mode,$type,$tab = 1)
    {
        $i = 0;
        foreach($arr as $k => $v)
        {
            if(is_array($v))
            {
                echo str_repeat("\t",$tab);
                if(is_int($k))
                {
                    $k = $v['_type'];
                    if(!$k)
                    {
                        switch($type)
                        {
                            case "topic":
                                $k = "post";
                                break;
                            case "user":
                            case "forum":
                                $k = "topic";
                                break;
                            default:
                                return false;
                                break;
                        }
                    }
                }
                unset($v['_type']);
                if($mode == "xml") echo "<$k>\n";
                elseif($mode == "json") echo "'$k': {\n";
                api::array_expand($v,$mode,$type,$tab+1);
                echo str_repeat("\t",$tab);
                if($mode == "xml") echo "</$k>\n";
                elseif($mode == "json") echo "}\n";
            }
            else
            {
                if($mode == "xml")
                {
                    echo str_repeat("\t",$tab);
                    if(is_int($k))
                    {
                        switch($type)
                        {
                            case "topic":
                                $k = "post";
                                break;
                            case "user":
                            case "forum":
                                $k = "topic";
                                break;
                            default:
                                return false;
                                break;
                        }
                    }
                    if($v !== "") echo "<$k>".htmlentities($v)."</$k>";
                    else echo "<$k />";
                    echo "\n";
                }
                elseif($mode == "json")
                {
                    echo str_repeat("\t",$tab);
                    if($v) echo "'$k': '$v'";
                    else echo "'$k': false";
                    $i++;
                    if($i < count($arr)-1) echo ",";
                    echo "\n";
                }
            }
        }
    }
    ## XML
    public function xml($query)
    {
        $type = $query['_type'];
        unset($query['_type']);
        echo "<$type>\n";
        api::array_expand($query,"xml",$type);
        echo "</$type>";
    }
    ## JSON
    public function json($query)
    {
        $type = $query['_type'];
        unset($query['_type']);
        echo "{\n\t'type': '$type',\n";
        api::array_expand($query,"json",$type);
        echo "}";
    }
}
$api = new api();
if($r = $_GET['r'])
{
    unset($_GET['r'],$_GET['css']);
    $r = explode(";",$r);
    $query = $api->query($r[0],$_GET,true);
    if(!$query) exit;
    if($_GET['m'] == "xml")
    {
        header('Content-Type: text/xml');
        $api->xml($query);
        exit;
    }
    elseif($_GET['m'] == "json")
    {
        header('Content-Type: application/json');
        $api->json($query);
        exit;
    }
    if(count($r) == 1) var_dump($query);
    else
    {
        if($r[1] == "get") var_dump($query[$r[2]]);
        else echo "NULL";
    }
    exit;
}
if($_GET['m'] == "parse")
{
    echo parser::parse($_POST['content']);
    exit;
}
?>